package com.yc.web;

import com.yc.damai.dto.Result;
import com.yc.damai.entity.DmOrderitem;
import com.yc.damai.entity.DmOrders;
import com.yc.damai.entity.DmPromotion;
import com.yc.damai.entity.DmPromotionDetail;
import com.yc.damai.util.JwtUtil;
import com.yc.web.feign.OtherAction;
import io.jsonwebtoken.Claims;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequestMapping("dacu")
public class DaCuDo {

    void begin(){
        System.out.println("====== 活动开始了 ======");
        DmPromotion p = (DmPromotion) redisTemplate.opsForValue().get("promotion");
        ValueOperations opsForValue = redisTemplate.opsForValue();
        for (DmPromotionDetail detail : p.getDetails()) {
            opsForValue.set("promotion:p_" + detail.getProduct().getId(),
                    detail.getNums());
        }
        redisTemplate.opsForValue().set("promotion.begin", true);
        otherAction.begin(p.getId());

        p.setStatus(1);
        redisTemplate.opsForValue().set("promotion", p);
    }
    void end(){
        System.out.println("====== 活动结束了 ======");
        DmPromotion p = (DmPromotion) redisTemplate.opsForValue().get("promotion");
        otherAction.end(p);
        // springboot 的bug不能模糊查询
        del("*promotion*");
    }

    @Autowired
    OtherAction otherAction;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    private TaskScheduler taskScheduler;

    @RequestMapping("ready")
    Result ready(){
        // 获取最近一次促销活动记录
        DmPromotion promotion = otherAction.getNoBegin();

        promotion.setBegin(new Timestamp(System.currentTimeMillis() + 1000 * 3));
        promotion.setEnd(new Timestamp(System.currentTimeMillis() + 1000 * 15));

        // 将促销数据存入redis
        redisTemplate.opsForValue().set("promotion", promotion);

        // 启动定时任务: 开始 + 结束
        taskScheduler.schedule(()->{
            begin();
        }, promotion.getBegin());

        taskScheduler.schedule(()->{
            end();
        }, promotion.getEnd());

        return new Result(1, "大促活动已启动", promotion);
    }

    @RequestMapping("commit")
    Result commit(DmOrderitem orderitem,
                  @CookieValue(required = false) String loginToken){
        if (redisTemplate.hasKey("promotion") == false) {
            return Result.error(-3, "秒杀活动已结束!");
        }
        if(redisTemplate.hasKey("promotion.begin") == false){
            return Result.error(-4, "秒杀活动未开始!");
        }

        if(loginToken == null){
            return Result.error(-1, "请先登录系统");
        }
        int uid = 0;
        Claims claims = JwtUtil.parseJWT(loginToken);
        Object id = claims.get("id");
        uid = Integer.parseInt(id + "");

        // 减库存
        ValueOperations opsForValue = redisTemplate.opsForValue();
        // 判断商品是否已经秒杀过 => redis
        if (redisTemplate.hasKey("promotion:p_" + orderitem.getPid() + ":u_" + uid)) {
            return Result.error(-2, "您已经秒杀过该商品");
        }

        Integer nums = (Integer) opsForValue.get("promotion:p_" + orderitem.getPid());
        if(nums == null){
            return Result.error(-5, "该商品未参与秒杀!");
        }

        nums -= orderitem.getCount();
        opsForValue.set("promotion:p_" + orderitem.getPid(), nums);
        opsForValue.set("promotion:p_" + orderitem.getPid() + ":u_" + uid, 1);

        // TODO 发送MQ消息
        DmOrders dmOrders = new DmOrders();
        dmOrders.setUid(uid);
        DmPromotion promotion = (DmPromotion) opsForValue.get("promotion");
        Integer price = promotion.getDetails()
                .stream()
                .filter(d -> d.getProduct().getId().equals(orderitem.getPid()))
                .collect(Collectors.toList())
                .get(0).getPrice();
        orderitem.setTotal((double) (orderitem.getCount() * price));
        dmOrders.setTotal(orderitem.getTotal());

        dmOrders.setItems(new ArrayList<>());
        dmOrders.getItems().add(orderitem);

        rabbitTemplate.convertAndSend("promotionQueue", dmOrders);
        return Result.ok("秒杀成功!");
    }

    @Autowired
    RabbitTemplate rabbitTemplate;

    @RequestMapping("getPromotion")
    DmPromotion getPromotion(){
        DmPromotion p = (DmPromotion) redisTemplate.opsForValue().get("promotion");
        return p;
    }

    @RequestMapping("keys")
    void del(String keys){
        System.out.println("keys = " + keys);
        redisTemplate.execute((RedisConnection conn) -> {
            Set<byte[]> set = conn.keys(keys.getBytes());
            for (byte[] key : set) {
                System.out.println("删除 key = " + new String(key));
                conn.del(key);
            }
            return null;
        });
    }

}
